﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using SmartSiteManagementSystem.IServices;
using SmartSiteManagementSystem.Models.Admin;
using SmartSiteManagementSystem.Utils;
using SmartSiteManagementSystem.AdminWeb.Extensions;
using System.Collections;
using Microsoft.AspNetCore.Mvc.Controllers;
using SmartSiteManagementSystem.AdminWeb.Common;

namespace SmartSiteManagementSystem.AdminWeb.Filter
{
    public class AdminRightAttribute :  IAuthorizationFilter
    {

        private readonly ILogger<AdminRightAttribute> _logger;
        private readonly IAdminService _adminService;
        private readonly IHttpContextAccessor _contextAccessor;
        public AdminRightAttribute(IAdminService adminService, IHttpContextAccessor contextAccessor, ILogger<AdminRightAttribute> logger)
        {
            _logger = logger;
            _adminService = adminService;
            _contextAccessor = contextAccessor;
        }

        public void OnAuthorization(AuthorizationFilterContext filterContext)
        {
            #region  跳过验证的判断代码,不需要验证的action增加[SkipFilterAttribute]标签


            //转换ActionDescriptor 
            var controllerActionDescriptor = filterContext.ActionDescriptor as ControllerActionDescriptor;

            //var actionName = controllerActionDescriptor.ActionName;
            //var controllerName = controllerActionDescriptor.ControllerName;

            var SkipFilters = controllerActionDescriptor.MethodInfo
            .GetCustomAttributes(typeof(SkipFilterAttribute), false);
            if (SkipFilters.Length > 0)
            {
                foreach (SkipFilterAttribute item in SkipFilters)
                {
                    if (item.FilterType == null)
                    {
                        return;
                    }
                    if (item.FilterType == this.GetType())
                    {
                        return;
                    }
                }
            }
            #endregion

            AdminUserInfo AdminObj = _contextAccessor.HttpContext.Session.Get<AdminUserInfo>(SessionCookieKeyHelper.SessionKey);

            if (AdminObj != null && AdminObj.AdminUserId > 0)
            {
                if (AdminObj.UserType == 2) { return ; }
                else
                {

                    if (!isRight(AdminObj.AdminUserId))
                    {
                        ActionResult result = new RedirectResult("/Home/noRight");
                        filterContext.Result = result;
                        return;
                    }

                }
                
            }
           
        }

        /// <summary>
        /// 判断是否有权限使用
        /// </summary>
        /// <param name="url"></param>
        /// <param name="adminUserId"></param>
        /// <returns></returns>
        private bool isRight(int adminUserId)
        {
            string currentFullUrl = _contextAccessor.HttpContext.Request.GetAbsoluteUri().ToLower();
            string currentUrl = _contextAccessor.HttpContext.Request.GetAbsolutePath().ToLower();
            string[] GetParam = null;
            if (currentFullUrl.LastIndexOf("?") > 0)
            {
                string pStr = currentFullUrl.Substring(currentFullUrl.LastIndexOf("?") + 1, (currentFullUrl.Length - currentFullUrl.LastIndexOf("?")) - 1);

                GetParam = pStr.Split('&');

            }

            string[] PostParam = null;
            if (!string.IsNullOrWhiteSpace(_contextAccessor.HttpContext.Request.ContentType) && _contextAccessor.HttpContext.Request.ContentType.Contains("multipart/form-data"))
            {
                if (_contextAccessor.HttpContext.Request.ContentLength != 0)
                {
                    PostParam = new string[_contextAccessor.HttpContext.Request.Form.Keys.Count()];
                    int i = 0;
                    foreach (var key in _contextAccessor.HttpContext.Request.Form.Keys)
                    {
                        PostParam[i] = key.ToString().ToLower() + "=" + _contextAccessor.HttpContext.Request.Form[key].ToString().ToLower();
                        i++;
                    }
                }
            }


            Hashtable rHt = _contextAccessor.HttpContext.Session.Get<Hashtable>("SSMS_AdminRightsList");
            if (rHt == null)
            {
                rHt = _adminService.GetAdminUserInfoRightList(adminUserId);
                _contextAccessor.HttpContext.Session.Set<Hashtable>("SSMS_AdminRightsList", rHt);
            }

            string[] RelParams = null;
            string KeyUrl = string.Empty;
            int isRightCount = 0;
            foreach (string Key in rHt.Keys)
            {
                if (Key.Contains(currentUrl))
                {
                    if (Key.LastIndexOf("?") > 0)
                    {
                        RelParams = Key.Substring(Key.LastIndexOf("?") + 1, (Key.Length - Key.LastIndexOf("?")) - 1).Split('&');
                        isRightCount = 0;
                        foreach (string Param in RelParams)
                        {
                            if (GetParam != null && GetParam.Length > 0)
                            {
                                foreach (string Gp in GetParam)
                                {
                                    if (Gp == Param)
                                        isRightCount = isRightCount + 1;
                                }
                            }
                            if (PostParam != null && PostParam.Length > 0)
                            {
                                foreach (string Pp in PostParam)
                                {
                                    if (Pp == Param)
                                        isRightCount = isRightCount + 1;

                                }
                            }
                        }
                        if (RelParams.Length == isRightCount)
                            return true;

                    }
                    else if (currentUrl == getAbsolutePath(Key).ToLower())
                    {
                        return true;
                    }
                }
            }

            
            return false;
        }

       
        private static string getAbsolutePath(string url)
        {
            if (string.IsNullOrEmpty(url))
                return null;
            if (url.LastIndexOf("?") > 0)
                return url.Substring(0, url.LastIndexOf("?"));
            return url;
        }
    }
}